package com.ccx.coachsite.http;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.os.AsyncTask;
import com.ccx.coachsite.util.Log;
import com.ccx.coachsite.util.StreamUtil;

public class Downloader extends AsyncTask<String, Integer, File> {

	private Progress entity;
	private HttpURLConnection conn;
	private File mFile;

	public Downloader(Progress entity) {
		init(entity.getFileName(), entity.getFileDir());
		this.entity = entity;
	}

	public Downloader(String fileDir, String fileName) {
		init(fileName, fileDir);

		entity = new Progress();
		entity.setFileDir(fileDir);
		entity.setFileName(fileName);
	}

	private void init(String fileName, String fileDir) {
		File dir = new File(fileDir);

		if (!dir.exists()) {
			dir.mkdirs();
		}

		mFile = new File(fileDir, fileName);
	}

	public void execute(String url) {
		super.execute(url);
	}

	@Override
	protected final File doInBackground(String... params) {

		if (params == null || params.length <= 0) {
			Log.e("url is null, download exit.");
			return null;
		}

		FileOutputStream f = createOutputStream(mFile);
		if (f == null) {
			Log.e("FileOutputStream is null, download exit.");
			return null;
		}

		String url = params[0];
		Log.d("url:" + url);

		try {
			URL u = new URL(url);
			conn = ((HttpURLConnection) u.openConnection());
			conn.setRequestMethod("GET");
			conn.setDoOutput(true);
			conn.connect();

			InputStream in = conn.getInputStream();
			int total = conn.getContentLength();
			int fix = 0;

			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = in.read(buffer)) > 0) {
				f.write(buffer, 0, len);
				fix += len;
				publishProgress(total, fix);
			}
		} catch (MalformedURLException e) {
			// e.printStackTrace();
			Log.e(e.getMessage(), e);
			deleteFile();
		} catch (IOException e) {
			// e.printStackTrace();
			Log.e(e.getMessage(), e);
			deleteFile();
		} finally {
			// Closes this stream.
			StreamUtil.closeSilently(f);
			
		}
		return null;
	}

	@Override
	protected final void onPostExecute(File result) {
		// Closes the connection to the HTTP server.
		if (conn != null) {
			conn.disconnect();
		}

		if (mListener != null) {
			mListener.onPostExecute(entity);
		}
	}

	@Override
	protected final void onProgressUpdate(Integer... values) {
		if (mListener != null) {
			mListener.onProgressUpdate(entity);
		}
	}

	private FileOutputStream createOutputStream(File file) {
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(file);
		} catch (FileNotFoundException e) {
			Log.e(e.getMessage() + ", file absolutePath:" + file.getAbsolutePath(), e);
			// e.printStackTrace();
		}

		return out;
	}

	// delete file if file.length() <=0
	private void deleteFile() {
		if (mFile != null)
			mFile.delete();
	}

	private ProgressListener<Progress> mListener;

	public void setProgressListener(ProgressListener<Progress> l) {
		mListener = l;
	}

}
